package com.open.capacity.forum.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.open.capacity.common.exception.service.ServiceException;
import com.open.capacity.common.util.PageUtil;
import com.open.capacity.common.web.CodeEnum;
import com.open.capacity.common.web.PageResult;
import com.open.capacity.common.web.Result;
import com.open.capacity.forum.constant.BusinessConstant;
import com.open.capacity.forum.constant.MetasConstant;
import com.open.capacity.forum.dao.ArticleDao;
import com.open.capacity.forum.dto.ArticleDto;
import com.open.capacity.forum.model.Article;
import com.open.capacity.forum.model.ArticleCategory;
import com.open.capacity.forum.model.ArticleCategoryRelation;
import com.open.capacity.forum.service.ArticleCategoryRelationService;
import com.open.capacity.forum.service.ArticleCategoryService;
import com.open.capacity.forum.service.ArticleService;
import com.open.capacity.forum.util.Commons;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ArticleServiceImpl extends ServiceImpl<ArticleDao, Article> implements ArticleService {

    @Resource
    private ArticleCategoryService categoryService;
    @Resource
    private ArticleCategoryRelationService categoryRelationService;


    @Override
    @Transactional
    public Result deleteArticleById(Long articleId) throws ServiceException {
        try {
            categoryRelationService.lambdaUpdate().eq(ArticleCategoryRelation::getArleid, articleId).remove();
            return removeById(articleId) ? Result.succeed(BusinessConstant.Default.succeed) : Result.failed(BusinessConstant.Default.failed);
        } catch (Exception e) {
            log.warn(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    public PageResult findArticlePage(Map<String, Object> params) throws ServiceException {
        try {
            PageUtil.pagePreProcess(params);
            List<ArticleDto> articleList = baseMapper.selectArticleByCondition(params);
            PageInfo<ArticleDto> pageInfo = new PageInfo<>(articleList);
            return PageResult.<ArticleDto>builder().code(CodeEnum.SUCCESS.getCode()).count(pageInfo.getTotal()).data(pageInfo.getList()).build();
        } catch (Exception e) {
            log.warn(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    public Result removeArticleCategory(Integer articleId, Integer[] ids) throws ServiceException {
        try {
            return baseMapper.deleteArticleCategory(articleId, ids) > 0 ? Result.succeed(BusinessConstant.Default.succeed) : Result.failed(BusinessConstant.Default.failed);
        } catch (Exception e) {
            log.warn(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    @Transactional
    public Result createdCategiryToArticle(Integer articleId, List<ArticleCategory> articleCategories) throws ServiceException {
        try {
            List<ArticleCategoryRelation> articleCategoryRelations = new ArrayList<>();
            categoryService.saveBatch(articleCategories);
            for (ArticleCategory articleCategory : articleCategories) {
                articleCategoryRelations.add(ArticleCategoryRelation.builder().arleid(articleId).cateid(articleCategory.getCateid()).build());
            }
            return appendCategoryToArticle(articleCategoryRelations);
        } catch (Exception e) {
            log.warn(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    public Result appendCategoryToArticle(List<ArticleCategoryRelation> categoryRelations) throws ServiceException {
        try {
            return categoryRelationService.saveBatch(categoryRelations) ? Result.succeed(BusinessConstant.Default.succeed) : Result.failed(BusinessConstant.Default.failed);
        } catch (Exception e) {
            log.warn(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    public PageResult findBlogPage(Map<String, Object> params) throws ServiceException {
        try {
            params.put("astate", MetasConstant.ArticleState.PUBLISH);
            PageUtil.pagePreProcess(params);
            List<ArticleDto> articleList = baseMapper.selectArticleByCondition(params);
            articleList.stream().peek((articleDto) -> articleDto.setContent(Commons.mdToHtml(articleDto.getDetail()))).collect(Collectors.toList());
            PageInfo<ArticleDto> pageInfo = new PageInfo<>(articleList);
            return PageResult.<ArticleDto>builder().code(CodeEnum.SUCCESS.getCode()).count(pageInfo.getTotal()).data(pageInfo.getList()).build();
        } catch (Exception e) {
            log.warn(e.getMessage());
            throw new ServiceException(e);
        }
    }
}
